package com.sh.d1.gatewayserver;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import com.sh.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

import java.util.concurrent.Executors;

/**
 * 订阅者
 */
public class RedisSusbcriber {

    static private final Logger LOGGER = LoggerFactory.getLogger(RedisSusbcriber.class);


    /**
     * REDIS通信通道
     */
    static public final String CHANNEL_DISCONNECT_DUPLICATE_LOGIN = "DisconnectDuplicateLogin";

    public RedisSusbcriber() {
    }

    /**
     * 开始订阅
     */
    static public void startSubcriber() {
        Executors.newSingleThreadExecutor().submit(RedisSusbcriber::subscribe);
    }

    /**
     * 订阅
     */
    static public void subscribe() {
    RedisUtil.getRedis().subscribe(new JedisPubSub() {
            @Override
            public void onMessage(String ch, String msg) {
                if (!CHANNEL_DISCONNECT_DUPLICATE_LOGIN.equals(ch) ||
                        null == msg || !msg.startsWith("{")) {
                    return;
                }
                JSONObject jsonObj = JSON.parseObject(msg);
                if (jsonObj.isEmpty() || !GatewayServer.getId().equals(jsonObj.getString("id"))) {
                    return;

                }
                int userId = jsonObj.getIntValue("userId");

                LOGGER.info(
                        "收到断开重复登录通知,userId={}"
                        , userId);

                Channel clientCh = ClientChannelGroup.getByUserId(userId);

                if (null != clientCh) {
                    clientCh.disconnect();
                } else {
                    cleanUserAtgatewayServerId(userId);
                }
            }
        }, CHANNEL_DISCONNECT_DUPLICATE_LOGIN);
    }

    /**
     * 清理用户所在网关服务器id
     *
     * @param userId
     */
    static private void cleanUserAtgatewayServerId(int userId) {
        if (userId <= 0) {
            return;
        }
        try (Jedis redis = RedisUtil.getRedis()) {
            String luaScript = "local key_user_N=\"User_\"  ..KEYS[1]\n" +
                    "local field_AtGatewayServerId=\"AtGatewayServerId\"\n" +
                    "local key_GatewayServer_N=\"GatewayServer_\" ..KEYS[2]\n" +
                    "local val_GatewayServerId=KEYS[2]\n" +
                    "local val=redis.call(\"hget\",key_user_N,field_AtGatewayServerId)\n" +
                    "if(val == val_GatewayServerId) then\n" +
                    "    redis.call(\"hdel\",key_user_N,field_AtGatewayServerId)\n" +
                    "    redis.call(\"hdel\",key_GatewayServer_N,key_user_N)\n" +
                    "    return 1\n" +
                    "end\n" +
                    "return 0";
//             redis.del("User_"+userId,"AtGatewayServerId");
            redis.eval(luaScript, 2,
                    String.valueOf(userId),
                    GatewayServer.getId());
        }
    }
}
